import json
import os
import random
import socket
import threading
import time

import win32api
import win32print

# 配置参数
HOST = 'www.whatwin.net'  # 服务器地址
PORT = 8083  # 服务器端口
HEARTBEAT_INTERVAL = 10  # 心跳间隔（秒）
RECONNECT_INTERVAL = 5  # 重新连接间隔（秒）


def send_heartbeat(sock):
    while True:
        try:
            # 发送心跳信息
            heartbeat_message = "HEARTBEAT"
            sock.sendall(heartbeat_message.encode())
            print(f"Sent heartbeat: {heartbeat_message}")
            # 等待下一次心跳
            time.sleep(HEARTBEAT_INTERVAL)
        except (socket.error, BrokenPipeError) as e:
            print(f"Error sending heartbeat: {e}")
            return


def printer_loading(filename, printer):
    print("开始打印...")
    try:
        win32api.ShellExecute(
            0,
            "print",
            filename,
            '/d:"%s"' % printer,
            ".",
            0,
        )
        print("打印指令已下发，请查看打印机...")
    except Exception as e:
        print(f'打印发生异常：{str(e)}')


def bytesToStr(byte_array):
    # 将字节数组解码为字符串（使用ASCII编码）
    my_string = byte_array.decode()

    # 打印字符串
    print(my_string.strip("\x00"))
    return my_string.strip("\x00")


def listen_to_channel(sock, isPrint, printer):
    while True:
        try:
            data = sock.recv(1024000)
            if data.startswith(b'\x02\x01'):
                # 使用切片操作去除头部指定字节
                new_data = data[len(b'\x02\x01'):]
                # 获取文件名
                fileName = bytesToStr(new_data[0:32])
                # 获取数据
                fileData = new_data[32:]
            else:
                print(f"Error22 receiving data exception")
                break
            # 接收文件数据
            received_file_name = os.path.join("FileStorage", fileName)
            with open(received_file_name, "wb") as localFile:
                localFile.write(fileData)
            time.sleep(1)
            print(f"文件已接收并保存到： {received_file_name}")
            # 进行打印
            if isPrint:
                printer_loading(received_file_name, printer)
        except (socket.error, BrokenPipeError) as e:
            print(f"Error receiving data: {e}")
            break


def connect_to_server(config_data):
    # 服务器主机和端口
    HOST = config_data['remoteHost']  # 服务器的IP地址
    PORT = config_data['remotePort']  # 服务器的端口号，与服务器配置一致
    isPrint = config_data['isPrint']  # 是否进行打印
    printer = win32print.GetDefaultPrinter()
    print("Use default printer:", printer)
    while True:
        try:
            # 创建 TCP 客户端套接字
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            # 连接到服务器
            sock.connect((HOST, PORT))
            if PORT == 8083:
                print(f"Success Connected to 测试环境【{HOST}:{PORT}】")
            else:
                print(f"Success Connected to 生产环境【{HOST}:{PORT}】")
            # 要添加的字节(注册)
            new_byte = b'\x01'

            # 注册识别号到服务端
            registerPackage = new_byte + config_data['IdentificationCode'].to_bytes(4, 'big')

            sock.send(registerPackage)
            print(f"Code：【{config_data['IdentificationCode']}】 ")

            # 启动心跳线程
            heartbeat_thread = threading.Thread(target=send_heartbeat, args=(sock,))
            heartbeat_thread.daemon = True
            heartbeat_thread.start()

            # 启动监听线程
            listen_to_channel(sock, isPrint, printer)

        except (socket.error, ConnectionRefusedError) as e:
            print(f"Connection error: {e}")
            print(f"Retrying in {RECONNECT_INTERVAL} seconds...")
            time.sleep(RECONNECT_INTERVAL)


def delete_files_in_directory(dir_list):
    # 检查文件夹路径是否存在
    if not os.path.exists(dir_list):
        print(f"The directory {dir_list} does not exist.")
        return
    for root, dirs, files in os.walk(dir_list):
        for file in files:
            file_path = os.path.join(root, file)
            try:
                os.remove(file_path)
                print(f"Deleted {file_path}")
            except Exception as e:
                print(f"Error deleting {file_path}: {e}")


if __name__ == "__main__":
    # 清空存储文件夹下的文件
    os.makedirs("FileStorage", exist_ok=True)
    delete_files_in_directory("./FileStorage")
    # 读取配置文件
    with open('config.json', 'r', encoding='utf-8') as file:
        config_data = json.load(file)
    # 判断是否有识别码
    if 'IdentificationCode' not in config_data:
        random_number = random.randint(100000000, 999999999)
        print('初始化：', random_number)
        config_data['IdentificationCode'] = random_number
        with open('config.json', 'w') as file:
            json.dump(config_data, file)
    # print(config_data)
    connect_to_server(config_data)
